.. _routes_develop:
######################################################
Руководство по разработке интеграционных маршрутов
######################################################
********************************************************************
Назначение и описание.
********************************************************************
========================================================================
Назначение
========================================================================
Частью приложения является интеграционный сервис, предназначеный для сопровождения логики, исполняемой на сервере приложения или интеграционном сервере.
Интеграционный сервис приложения является модульным и расширяемым решением.
Основой сервиса является **маршрут**. Маршрут - поток исполняемой логики, позволяющий описывать исполнение процесса обработки данных ("сообщений") или взаимодействие с внешними системами, такими как:
* Веб сервисы
* Базы данных
* BMP системы
* Очереди сообщений
* и др..
| Интеграционные маршруты могут быть подключены как к запросам приложения к адаптерам, так и к ответам адаптеров на запросы.
| Подключение маршрутов к запросам осуществляется с помощью маппинга маршрута к запросам системы к адаптерам (см: :numref:`routes_mapping`).
| Список требуемых внешних маршрутов динамически строится в зависимости от схемы, метода и типа запроса.
| Последовательность выполнения внешних маршрутов определяется приоритетом маршрута в маппинге.
========================================================================
Описание структуры маршрута
========================================================================
---------------------------------------------------------------------------
Элементы маршрута
---------------------------------------------------------------------------
Маршрут состоит из следующих элементов:
*Прием потока обработки данных (from)*
| Элемент маршрута, описывающий начало маршрута, источник данных для получения данных.
| По умолчанию данные поступают из бекенда, в ходе исполнения процесса пользователями. Bдентификатор маршрута, соответствует идентификатору маршрута в системе.
*Передача потока обработки данных (to)*
Элемент маршрута, описывающий передачу данных внешней системе или в другой маршрут обработки данных.
*Процесс (process)*
Элемент описывает использование интерфейса Processor для обработки данных в ветке потока обработки данных.
*Java Bean (bean)*
Элемент описывает использование JavaBean для обработки данных в ветке потока обработки данных.
*Установка тела сообщения (setBody)*
Элемент маршрута, позволяющий изменить тело сообщения (например сформировать запрос к внешней системе или изменить значение атрибутов для сохранения на адаптере.
*Установка заголовка сообщения (setHeader)*
Элемент маршрута, позволяющий установить заголовок сообщения
*Удалить заголовок (removeHeader)*
Элемент маршрута, позволяющий удалить заголовок сообщения
*Удалить заголовки (removeHeaders)*
Элемент маршрута, позволяющий удалить заголовки сообщения по шаблону
*Преобразование (transform)*
Элемент transform предназначен для трансформации тела сообщения (изменения значений атрибутов, изменения тела сообщения для передачи внешней системе.
*Выбор (choice)*
Элемент, позволяющий организовать ветвление в процессе обработки данных.
*Условие (when)*
Элемент, описывающий одну из веток ветвления потока обработки по условию.
*Иначе (otherwise)*
Элемент, описывающий альтернативную ветку потока, в случае, если условия ветвления не были выполнены.
*Ошибка (onException)*
Элемент маршрута, описывающий процесс обработки данных в случае появления ошибки.
.. warning::
Классы JavaBeans и Processors, используемые в маршрутах должны быть размещены на сервере. Соответствующие им компоненты маршрута должны быть настроены в реестре компонентов (см: :numref:`registry_tune`).
---------------------------------------------------------------------------
Описание маршрута в конфигурационной базе
---------------------------------------------------------------------------
| Конфигурации маршрутов хранятся в формате JSON в таблице **ROUTE** конфигурационной базе приложения.
| Параметры запуска внешнего маршрута, такие как схема, тип, метод, приоритет, а также статус и синхроность/ассинхроность, хранятся в таблице **ROUTE_MAPPING**.
| Конфигурации компонентов реестра хранятся в таблице **ENDPOINTS**.
Таблица ROUTE имеет следующие поля:
* id – идентификатор маршрута;
* tenant_id – идентификатор tenant;
* definition – описание маршрута в формате JSON;
* modify_date – дата последнего изменения маршрута;
* status – статус маршрута. Данный параметр позволяет включать/отключать маршрут глобально в рамках данного приложения.
Таблица ROUTE_MAPPING имеет следующие поля:
* id – идентификатор маршрута;
* tenant_id – идентификатор tenant;
* schema_id – идентификатор схемы запроса;
* method – метод запроса (GET, POST);
* type – тип маршрута, определяющий принадлежность к преинтерсептору или постинтерсептеру ;
* priority – приоритет маршрута в списке маршрутов данного запроса;
* route_id – ссылка на описание маршрута в таблице ROUTE;
* status – статус, позволяющий включать или отключать маршрут в рамках обработки для данного типа запроса;
* async – параметр, определяющий синхронность/асинхронность выполнения маршрута.
Таблица ENDPOINTS имеет следующие поля:
* id– идентификатор компонента;
* tenant_id – идентификатор tenant;
* name - имя компонента;
* type -тип компонента;
* definition - описание компонента;
* status - статус компонента;
* modify_date – дата последнего изменения ;
========================================================================
Описание структуры сообщения
========================================================================
По маршруту обрабатываются сообщения. Сообщение состоит из:
*Заголовки (Headers)*
| Описываются параметры сообщения.
| Параметры запроса к адаптеру описаны в заголовке **requestParams**.
*Тело сообщения (Body)*
| Описывается тело сообщения, например перечень атрибутов записи.
****************************************************************************************************************************************
Правила формирования JSON описания маршрута.
****************************************************************************************************************************************
========================================================================
Структура JSON маршрута
========================================================================
JSON описание маршрута используется для построения XML описания на языке Apche Camel DSL.
При этом JSON представляет собой усеченную версию описания маршрута, в которой отсутствуют некоторые атрибуты и вершины.
Необходимые недостающие вершины автоматически добавляются в процессе трансляции из JSON в XML. Таким образом, процессе трансляции, к создаваемому внешнему маршруту будет добавлен аттрибут идентификатора маршрута, и вершина from, которые отсутствуют в JSON, но информация о которых приходит из Базы Данных при получении описания маршрута.
JSON описание должно содержать всю необходимую информацию о маршруте, расположенную после вершины from.
Пример JSON описания внешнего маршрута приведен ниже:
::
{"route":
[{"setHeader":{"name":"RT000000000000", "type":"constant", "value":"This text1 added by async Enriching Route RT000000000000"}},
{"removeHeader":{"name":"RT000000000000"}},
{"setHeader":{"name":"RT000000000000", "type":"constant", "value":"This text2 added by async Enriching Route RT000000000000"}},
{"setHeader":{"name":"currentTime", "type":"groovy", "value":"new java.util.Date().getTime()/1000"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"WARN","showHeaders":"true","showException":"false","showCaughtException":"false"}}},
{"to":{"uri":"sql:SELECT * FROM route_mapping?dataSource=#postgresSQL"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}},
{"setBody":{"type":"constant", "value":"Test Body"}},
{"to":{"uri":"http://webservice:8080/wsdl/ExtSys_SAES2_MI.wsdl?httpMethod=GET"}},
{"transform":{"type":"simple", "value":"${body}"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"WARN","showHeaders":"true","showException":"false","showCaughtException":"false"}}},
{"choice":[
{"when":[ {"type":"groovy","condition":"request.headers['RT000000000000'] == null"},
{"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by the route RT000000000000C1 condition 1"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]},
{"when":[ {"type":"groovy","condition":"request.headers['RT000000000000'] != null"},
{"setHeader":{"name":"RT000000000000C1", "type":"constant", "value"="This header was added by the route RT000000000000C1 condition 2"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]},
{"otherwise":[
{"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by the route RT000000000000C1 condition otherwise"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]}]},
{"onException": [ {"exception":"java.lang.NullPointerException"}, {"setHeader":{"name":"RT000000000000", "type":"constant", "value":"This header was added by the exception handler"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"ERROR","showHeaders":"true","showException":"true","showCaughtException":"true"}}}
]}
]
}
..
.. note:: В теле маршрута можно передать XML описание маршрута, для этого XML должен быть преобразован в JSON строку. Тело запроса должно содержать только XML.
Прмер такой строки приведен ниже:
::
"........"
..
JSON описание маршрута должно начинаться с корневого элемента “route”.
Далее элемент “route” содержит список JSON компонентов, последовательность которых полностью определяет описание маршрута за исключением вершины from.
::
{"route":[{элемент1:{набор параметров}, элемент2:{набор параметров}... элементN:{набор параметров}]}
..
========================================================================
Типовая структура элемента маршрута
========================================================================
Многие из элементов языка Spring DSL могут быть описаны объектом JSON, содержащей несколько ключевых параметров.
В текущей версии приложения допускается использовать следующие не обязательные параметры: uri, options, ref, method.
В свою очередь, параметр options, также должен содержать объект JSON состоящий из допустимых опций указанного элемента.
В общем случае JSON формат описания типового элемента имеет следующий вид:
::
{"name":{"uri":"url value","options":{"option1":"value1","option2":"value2",optionN":"valueN"},“ref”:”value”, “method”:”method_name”}}
..
* name – имя элемента (обязательный параметр);
* uri – uri (если необходимо для данного элемента);
* options – список возможных опций элемента (если необходимо для данного элемента). В текущей версии данный параметр задает опции параметра uri;
* ref – ссылка на другие элементы (если необходимо для данного элемента);
* method – вызываемый метод (если необходимо для данного элемента).
========================================================================
Элемент to
========================================================================
Например, для элемента типа “to” описание в формате JSON может иметь следующий вид:
::
{"to":{"uri":"direct:start"}},
{"to":{"uri":"sql:SELECT * FROM route_mapping?dataSource=#postgresSQL"}},
{"to":{"uri":"http://mgts-remedytst02:8080/wsdl/ExtSys_SAES2_MI.wsdl", "options":{"httpMethod":"GET"}}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}
..
========================================================================
Элемент bean
========================================================================
Элемент “bean” может быть описан следующим образом:
::
{"bean":{"ref":"testBean"}},
{"bean":{"ref":"testBean", "method":"removeComment"}},
{"bean":{"ref":"testBean", "method":"removeComment(${body}, ${headers})"}}
..
========================================================================
Элемент process
========================================================================
Элемент “process” можно описать так:
::
{"process":{"ref":"testProcess"}}
..
========================================================================
Элемент setBody
========================================================================
Элемент setBody предназначен для установки нового значения тела сообщения. JSON формат этого элемента имеет следующую структуру:
::
{"setBody":{"type":"способ указания значения тела", "value":"новое значение тела"}}
..
Для указания значения тела сообщения могут быть применены разного рода конструкции, основанные на скриптовых языках (simple, spel, groovy) или просто константа (constant).
Рассмотрим некоторые JSON примеры этого элемента.
::
{"setBody":{"type":"constant", "value":"New Body"}},
{"setBody":{"type":"groovy", "value":"new java.util.Date().getTime()/1000"}},
{"setBody":{"type":"spel", "value":"#{request.body['-method'] “ }
..
========================================================================
Элемент setHeader
========================================================================
Элемент setHeader предназначен для установки значения заголовка сообщения. JSON формат данного элемента имеет следующую структуру:
::
{"setHeader":{”name":"имя заголовка", "type":"способ указания значения заголовка", "value":"значение заголовка"}}
..
Для указания значения заголовка могут быть применены разного рода конструкции, основанные на скриптовых языках (simple, spel, groovy) или просто константа (constant).
Рассмотрим некоторые JSON примеры этого элемента.
::
{"setHeader":{"name":"RT000000000000","type":"constant","value":"New Header"}},
{"setHeader":{"name":"RT000000000001","type":"groovy", "value":"new java.util.Date().getTime()/1000"}},
{"setHeader":{"name":"RT000000000002",""type":"spel", "value":"#{request.body['-method'] “ }
..
========================================================================
Элемент transform
========================================================================
Элемент transform предназначен для трансформации тела сообщения. JSON формат данного элемента имеет следующую структуру:
::
{"transform":{"type":"тип правила трансформации", "value":"правило трансформации"}}
..
Для указания значения типа правила трансформации могут быть применены разного рода конструкции, основанные на скриптовых языках (simple, spel, groovy).
Рассмотрим некоторые JSON примеры этого элемента.
::
{"transform":{"type":"simple", "value":"${body}"}},
{"transform":{"type":"spel", "value":"#{request.body}"}}
..
..
========================================================================
Элемент removeHeader
========================================================================
Элемент removeHeader предназначен для удаления заголовка сообщения. JSON формат данного элемента имеет следующую структуру:
::
{"removeHeader":{"name":"имя заголовка"}}
..
Рассмотрим JSON пример этого элемента.
::
{"removeHeader":{"name":"RT000000000000"}}
..
========================================================================
Элемент removeHeaders
========================================================================
Элемент removeHeaders предназначен для удаления списка заголовков сообщения. JSON формат данного элемента имеет следующую структуру:
::
{"removeHeaders":{"pattern":"шаблон имен для удаления","excludePattern":"шаблон имен для исключения удаления"}}
..
Рассмотрим JSON пример этого элемента.
::
{"removeHeaders":{"pattern":"*", "excludePattern":"Content-Type|Content-Length|MIME-Version"}}
..
========================================================================
Элементы choice и when
========================================================================
Элементы choice и when предназначены для организации ветвлений внутри маршрута. JSON формат для данного случая имеет следующую структуру:
::
{"choice":[
{"when:[{"type":"тип условного выражения","condition":”условное выражение”},{элемент1}, {элемент2} … {элементN}]},
{"when:[{"type":"тип условного выражения","condition":”условное выражение”},{элемент1}, {элемент2} … {элементN}]},
{"when:[{"type":"тип условного выражения","condition":”условное выражение”},{элемент1}, {элемент2} … {элементN}]},
{"otherwise":[{элемент1}, {элемент2} … {элементN}]} ]}
..
Рассмотрим JSON пример данной структуры.
::
{"choice":[
{"when":[ {"type":"groovy","condition":"request.headers['RT000000000000'] == null"},
{"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by the condition 1"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]},
{"when":[ {"type":"groovy","condition":"request.headers['RT000000000000'] != null"},
{"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by the condition 2"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]},
{"otherwise":[
{"setHeader":{"name":"RT000000000000C1", "type":"constant", "value":"This header was added by condition otherwise"}},
{"to":{"uri":"log:ru.igtel", "options":{"level":"INFO","showHeaders":"true","showException":"false","showCaughtException":"false"}}}]}]}
..
========================================================================
Элемент обработки исключения onException
========================================================================
Элемент onException используется для организации обработки исключения внутри маршрута. В каждом маршруте может присутствовать несколько секций обработки исключения. JSON формат для данного случая имеет следующую структуру:
::
{"onException": [{"exception":"тип исключения"}, {элемент1}, {элемент2} … {элементN}]}
Рассмотрим JSON пример данной структуры.
::
{"onException": [
{"exception":"java.lang.NullPointerException"},
{"setHeader":{"name":"RT000000000000", "type":"constant", "value":"This header was added by the exception handler"}}, {"to":{"uri":"log:ru.igtel", "options":{"level":"ERROR","showHeaders":"true","showException":"true","showCaughtException":"true"}}}
]}
********************************************************************
Примеры
********************************************************************
========================================================================
Пример настройки компонента "SqlComponent" в реестре
========================================================================
::
{
"driver": "org.postgresql.Driver",
"username": "sa",
"password": "123456",
"url": "jdbc:h2:D:/var3/db/sgate;DB_CLOSE_DELAY=-1;TRACE_LEVEL_FILE=1;DATABASE_TO_UPPER=false;MODE=POSTGRES"
}
..